home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2000 October
/
CHIP Turkiye Ekim 2000.iso
/
prog
/
naps
/
04
/
setup.exe
/
Gnucleus
/
GnucleusDoc.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2000-07-15
|
18KB
|
687 lines
/********************************************************************************
Gnucleus - A node application for the Gnutella network
Copyright (C) 2000 John Marshall
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For support, questions, comments, etc...
E-Mail:
swabby@c0re.net
Address:
21 Cadogan Way
Nashua, NH, USA 03062
********************************************************************************/
// GnucleusDoc.cpp : implementation of the CGnucleusDoc class
//
#include "stdafx.h"
#include "GnucleusDoc.h"
#include "Gnucleus.h"
#include "ViewSearch.h"
#include "ViewSearchSpy.h"
#include "MainFrm.h"
#include "GnuTransfer.h"
#include "GnuHash.h"
#include "GnuControl.h"
#include "IPFilter.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
void CGnucleusDoc::QueueCache::PurgeEarliestHostPort(void)
{
using namespace std;
list<set<CString>::iterator>::iterator iter =
mHostPortsQueue.begin();
mHostPorts.erase(*iter);
mHostPortsQueue.pop_front();
}
void CGnucleusDoc::QueueCache::AppendLatestHostPort
(
const CString& inHostPort
)
{
using namespace std;
set<CString>::iterator setIter =
mHostPorts.insert(inHostPort).first;
mHostPortsQueue.push_back(setIter);
}
/////////////////////////////////////////////////////////////////////////////
// CGnucleusDoc
IMPLEMENT_DYNCREATE(CGnucleusDoc, CDocument)
BEGIN_MESSAGE_MAP(CGnucleusDoc, CDocument)
//{{AFX_MSG_MAP(CGnucleusDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGnucleusDoc construction/destruction
CGnucleusDoc::CGnucleusDoc()
{
GnuComm = new CGnuControl(this);
TotalHosts = 0;
m_EstSpeed = 0;
ActiveUploads = 0;
m_readCount = 0;
m_writeCount = 0;
m_hLangDLL = NULL;
// Load INI, Host file, and shared directories
ReadINI();
ReadHostsFile ();
LoadShare();
}
CGnucleusDoc::~CGnucleusDoc()
{
delete GnuComm;
WriteINI();
WriteHostsFile();
CIPFilter::Shutdown ();
}
BOOL CGnucleusDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
TotalHosts = 0;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
void CGnucleusDoc::UpdateSearchViews(packet_QueryReply *QueryReply)
{
bool Found = 0;
CString Title;
POSITION pos = GetFirstViewPosition();
while (pos != NULL)
{
CView* pView = GetNextView(pos);
pView->GetParentFrame()->GetWindowText(Title);
if(Title.Find("Searching for \"") != -1)
if(((CViewSearch *) pView)->myGuid == QueryReply->Header.Guid)
{
((CViewSearch *) pView)->UpdateResults((byte *) QueryReply);
return;
}
}
}
void CGnucleusDoc::ReadHostsFile()
{
CStdioFile infile;
CString hostFile = "Gnucleus.net";
if (infile.Open(hostFile, CFile::modeCreate | CFile::modeNoTruncate
| CFile::modeRead))
{
CString HostPort;
while (infile.ReadString(HostPort))
{
int a=-1, b=-1, c=-1, d=-1;
::sscanf (HostPort, "%d.%d.%d.%d", &a, &b, &c, &d);
if (a > 0 && b > -1 && c > -1 && d > -1)
{
if (CIPFilter::IsPrivateIP(a, b, c, d, a, b, c, d) == 0 &&
CIPFilter::AllowIP (a, b, c, d))
{
HostPort.Remove('\r');
HostPort.Remove('\n');
SavedHosts.AddTail(HostPort);
}
}
}
infile.Close();
}
}
void CGnucleusDoc::WriteHostsFile()
{
CString HostPort, OldHost;
CString hostFile = "Gnucleus.net";
using namespace std;
while (mQueueCache.mHostPortsQueue.size())
{
list<set<CString>::iterator>::iterator iter =
mQueueCache.mHostPortsQueue.begin();
while (SavedHosts.GetCount() >= 500)
{
OldHost = SavedHosts.RemoveTail();
// TRACE("Removed old host %s from SavedHost\n",OldHost);
}
SavedHosts.AddHead(**iter);
// TRACE("Adding %s to head of SavedHost\n", (LPCTSTR)(**iter));
mQueueCache.PurgeEarliestHostPort();
}
CStdioFile outfile;
if (outfile.Open( hostFile, CFile::modeCreate | CFile::modeWrite))
{
while( !SavedHosts.IsEmpty() )
{
HostPort = SavedHosts.RemoveHead();
HostPort += "\r\n";
outfile.WriteString(HostPort);
}
outfile.Close();
}
}
void CGnucleusDoc::ReadINI()
{
char buffer[256];
CString temp, convert, dir;
CString iniFile = ".\\Gnucleus.ini";
// Connect Settings
GetPrivateProfileString("Connect", "Port", "0", buffer, 256, iniFile);
m_ConstPort = atol(buffer);
if(m_ConstPort)
GnuComm->localPort = m_ConstPort;
GetPrivateProfileString("Connect", "Speed", "0", buffer, 256, iniFile);
m_ConnectSpeed = atol(buffer);
GetPrivateProfileString("Connect", "Force IP", "0.0.0.0", buffer, 256, iniFile);
CString strIP(buffer);
m_ForceIP = StrtoIP(strIP);
GetPrivateProfileString("Connect", "Monitor Type", "2", buffer, 256, iniFile);
m_MonitorType = atoi(buffer);
GetPrivateProfileString("Connect", "ConnectNum", "3", buffer, 256, iniFile);
m_ConnectNum = atoi(buffer);
GetPrivateProfileString("Connect", "Timeout", "4", buffer, 256, iniFile);
m_TimeoutConnect = atoi(buffer);
GetPrivateProfileString("Connect", "Drop for Incoming", "0", buffer, 256, iniFile);
m_DropForIncoming = (0 != atoi(buffer));
// Search Filter Settings
int loop;
for(loop = 0; ; ++loop)
{
temp.Format ("Item%ld", loop);
if (GetPrivateProfileString ("Search Filter", temp, "", buffer, 256, iniFile) > 0)
{
convert = buffer;
int pos = convert.Find(':');
BlockedSearch Search;
Search.Name = convert.Mid(pos + 1);
Search.Permis = convert.GetAt(0);
SearchFilter.push_back(Search);
}
else
{
break;
}
}
if( SearchFilter.empty() )
{
BlockedSearch Search;
Search.Name = "*.*";
Search.Permis = 'A';
SearchFilter.push_back(Search);
}
// Filter Settings
for (loop = 0; ; ++loop)
{
temp.Format ("Item%ld", loop);
if (GetPrivateProfileString ("IP Filter", temp, "", buffer, 256, iniFile) > 0)
{
convert = buffer;
convert.Replace("*", "-1");
convert.Replace('.', ':');
CIPFilter::AddFilter (convert);
}
else
{
break;
}
}
std::vector<CString> FilterList;
CIPFilter::GetConfigStrings( FilterList );
if( FilterList.empty() )
CIPFilter::AddFilter("A:-1:-1:-1:-1");
// Search Settings
GetPrivateProfileString("Search", "Max Replies", "64", buffer, 256, iniFile);
m_MaxReplies = atoi(buffer);
// Download Settings
char * default_dir = new char[MAX_PATH]; // for non default desktop directories
LPITEMIDLIST lp_itemid_list;
LPMALLOC lp_sh_malloc;
SHGetMalloc(&lp_sh_malloc);
SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &lp_itemid_list);
SHGetPathFromIDList(lp_itemid_list, default_dir);
lp_sh_malloc->Free(lp_itemid_list); // free ITEMID list
// lp_sh_malloc->Release(); //?
GetPrivateProfileString("Download", "DownloadDir", _T(default_dir), buffer, 256, iniFile);
m_DownloadDir = buffer;
delete [] default_dir;
GetPrivateProfileString("Download", "Max Downloads", "2", buffer, 256, iniFile);
m_MaxDownloads = atoi(buffer);
GetPrivateProfileString("Download", "Auto Clear", "1", buffer, 256, iniFile);
m_AutoClearDL = atoi(buffer) ? true : false;
GetPrivateProfileString("Download", "Timeout", "15", buffer, 256, iniFile);
m_TimeoutDownload = atoi(buffer);
GetPrivateProfileString("Download", "Resume", "1", buffer, 256, iniFile);
m_ResumeDL = atoi(buffer) ? true : false;
// Upload Settings
GetPrivateProfileString("Upload", "Max Uploads", "4", buffer, 256, iniFile);
m_MaxUploads = atoi(buffer);
GetPrivateProfileString("Upload", "Auto Clear", "1", buffer, 256, iniFile);
m_AutoClearUL = atoi(buffer) ? true : false;
for (loop = 0; ; ++loop)
{
temp.Format ("Dir%ld", loop);
if (GetPrivateProfileString ("Share", temp, "", buffer, 256,
iniFile) > 0)
{
dir = buffer;
LockUploadData (true);
SharedDirList.push_back(dir);
SharedDirCount.push_back(0);
SharedDirSize.push_back(0);
UnlockUploadData (true);
}
else
break;
}
// Bandwidth Settings
GetPrivateProfileString("Bandwidth", "Drop for Downloads", "0", buffer, 256, iniFile);
m_AutoDropDL = atoi(buffer) ? true : false;
GetPrivateProfileString("Bandwidth", "Drop for Uploads", "0", buffer, 256, iniFile);
m_AutoDropUL = atoi(buffer) ? true : false;
GetPrivateProfileString("Bandwidth", "Total Limit", "0", buffer, 256, iniFile);
m_LimitTotal = atoi(buffer);
GetPrivateProfileString("Bandwidth", "Upload Limit", "0", buffer, 256, iniFile);
m_LimitUp = atoi(buffer);
GetPrivateProfileString("Bandwidth", "Visual", "1", buffer, 256, iniFile);
m_BwVisual = atoi(buffer);
// Language Settings
GetPrivateProfileString("Language", "DLL_Selected", "Default", buffer, 256, iniFile);
m_strLangDLLex = buffer;
}
void CGnucleusDoc::WriteINI()
{
CString temp,convert;
CString iniFile = ".\\Gnucleus.ini";
// Connect Settings
WritePrivateProfileString("Connect", "Port", DWrdtoStr(m_ConstPort), iniFile);
WritePrivateProfileString("Connect", "Speed", DWrdtoStr(m_ConnectSpeed), iniFile);
WritePrivateProfileString("Connect", "Force IP", IPtoStr(m_ForceIP), iniFile);
WritePrivateProfileString("Connect", "Monitor Type", DWrdtoStr(m_MonitorType), iniFile);
WritePrivateProfileString("Connect", "ConnectNum", DWrdtoStr(m_ConnectNum), iniFile);
WritePrivateProfileString("Connect", "Timeout", DWrdtoStr(m_TimeoutConnect), iniFile);
WritePrivateProfileString("Connect", "Drop for Incoming", DWrdtoStr(m_DropForIncoming), iniFile);
int loop;
// Search Filter
WritePrivateProfileString("Search Filter", NULL, NULL, iniFile); // First clear out the IPFilters ini file section
std::vector<BlockedSearch>::iterator itSearch;
for (loop = 0, itSearch = SearchFilter.begin (); itSearch != SearchFilter.end (); loop++, itSearch++)
{
temp.Format ("Item%ld", loop);
convert = (*itSearch).
Name;
convert.Insert(0, ":");
convert.Insert(0, (*itSearch).Permis);
WritePrivateProfileString ("Search Filter", temp, convert,
iniFile);
}
// Filter Settings
WritePrivateProfileString("Filter", NULL, NULL, iniFile); //First clear out the IPFilters ini file section
std::vector<CString>::iterator it;
std::vector<CString> strings;
CIPFilter::GetConfigStrings (strings); // Then get the new config strings to write out to the ini file
for (loop = 0, it = strings.begin (); it != strings.end (); loop++, it++)
{
temp.Format ("Item%ld", loop);
convert = *it;
convert.Replace("-1", "*");
convert.Replace(':', '.');
convert.SetAt(1, ':');
WritePrivateProfileString ("IP Filter", temp, convert, iniFile);
}
// Search Settings
WritePrivateProfileString("Search", "Max Replies", DWrdtoStr(m_MaxReplies), iniFile);
// Download Settings
WritePrivateProfileString("Download", "DownloadDir", m_DownloadDir, iniFile);
WritePrivateProfileString("Download", "Max Downloads", DWrdtoStr(m_MaxDownloads), iniFile);
WritePrivateProfileString("Download", "Auto Clear", WrdtoStr( (int)m_AutoClearDL), iniFile);
WritePrivateProfileString("Download", "Timeout", DWrdtoStr(m_TimeoutDownload), iniFile);
WritePrivateProfileString("Download", "Resume", WrdtoStr( (int)m_ResumeDL), iniFile);
// Upload Settings
WritePrivateProfileString("Upload", "Max Uploads", DWrdtoStr(m_MaxUploads), iniFile);
WritePrivateProfileString("Upload", "Auto Clear", WrdtoStr( (int)m_AutoClearUL), iniFile);
// First clear out the IPFilters ini file section
WritePrivateProfileString("Share", NULL, NULL, iniFile);
LockUploadData (false);
for (loop = 0, it = SharedDirList.begin (); it != SharedDirList.end ();
loop++, it++)
{
temp.Format ("Dir%ld", loop);
WritePrivateProfileString ("Share", temp, (*it), iniFile);
}
UnlockUploadData (false);
// Bandwidth Settings
WritePrivateProfileString("Bandwidth", "Drop for Downloads", WrdtoStr( (int)m_AutoDropDL), iniFile);
WritePrivateProfileString("Bandwidth", "Drop for Uploads", WrdtoStr( (int)m_AutoDropUL), iniFile);
WritePrivateProfileString("Bandwidth", "Total Limit", DWrdtoStr(m_LimitTotal), iniFile);
WritePrivateProfileString("Bandwidth", "Upload Limit", DWrdtoStr(m_LimitUp), iniFile);
WritePrivateProfileString("Bandwidth", "Visual", DWrdtoStr(m_BwVisual), iniFile);
// Language Settings
WritePrivateProfileString("Language", "DLL_Selected", m_strLangDLLex, iniFile);
}
void CGnucleusDoc::LoadShare()
{
CString Path;
std::vector<CString>::iterator itDir;
std::vector<DWORD>::iterator itCount;
std::vector<DWORD>::iterator itSize;
LockUploadData (true);
for (itDir = SharedDirList.begin(), itCount = SharedDirCount.begin(), itSize = SharedDirSize.begin();
itDir != SharedDirList.end(), itCount != SharedDirCount.end(), itSize != SharedDirSize.end();
itDir++, itCount++, itSize++)
{
Path = (*itDir);
if(Path.Find("Recursive") != -1)
RecurseShare(Path.Mid(0, Path.Find(',')), 1, (*itCount), (*itSize));
else
RecurseShare(Path, 0, (*itCount), (*itSize));
}
UnlockUploadData (true);
}
void CGnucleusDoc::RecurseShare(CString File, bool doRecurse, DWORD &DirCount, DWORD &DirSize)
{
CFileFind finder;
// build a string with wildcards
CString strWildcard(File);
CString file_name;
if(strWildcard.GetAt( strWildcard.GetLength() - 1) != '\\')
strWildcard += _T("\\*.*");
else
strWildcard += _T("*.*");
// start working for files
BOOL bWorking = finder.FindFile(strWildcard);
while (bWorking)
{
bWorking = finder.FindNextFile();
// skip . and .. files
if (finder.IsDots())
continue;
// if it's a directory, recursively search it
if (finder.IsDirectory())
{
CString str = finder.GetFilePath();
if(doRecurse)
RecurseShare(str, 1, DirCount, DirSize);
}
else
{
SharedFile addFile;
addFile.FileDir = finder.GetFilePath();
addFile.FileName = addFile.FileDir.Mid( addFile.FileDir.ReverseFind('\\') + 1);
addFile.FileDir.MakeLower();
SharedFiles.push_back(addFile);
SharedSizes.push_back(finder.GetLength());
DirCount++;
DirSize += finder.GetLength();
}
}
finder.Close();
}
void CGnucleusDoc::AddToQueueCache(const CString& inHostPort)
{
using namespace std;
if (mQueueCache.mHostPorts.end() ==
mQueueCache.mHostPorts.find(inHostPort))
{
if (500 == mQueueCache.mHostPortsQueue.size())
mQueueCache.PurgeEarliestHostPort();
mQueueCache.AppendLatestHostPort(inHostPort);
}
}
void CGnucleusDoc::RemoveEarliestHostPort(CString* outHostPort)
{
ASSERT(outHostPort);
outHostPort->Empty();
using namespace std;
if (!mQueueCache.mHostPortsQueue.empty())
{
list<set<CString>::iterator>::iterator iter =
mQueueCache.mHostPortsQueue.begin();
*outHostPort = **iter;
mQueueCache.PurgeEarliestHostPort();
}
}
void CGnucleusDoc::LockUploadData (bool writeAccess)
{
while (m_writeCount) // Writing blocks everyone
{
::Sleep (20);
}
if (writeAccess)
{
m_writeCount++;
ASSERT (m_writeCount == 1);
while (m_readCount)
{
::Sleep (20);
}
}
else
{
m_readCount++;
}
}
void CGnucleusDoc::UnlockUploadData (bool writeAccess)
{
if (writeAccess)
{
m_writeCount--;
ASSERT (m_writeCount == 0);
}
else
{
m_readCount--;
ASSERT (m_readCount >= 0);
}
}
/////////////////////////////////////////////////////////////////////////////
// CGnucleusDoc serialization
void CGnucleusDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
void CGnucleusDoc::UpdateSpy( CString searchText )
{
CString Title;
POSITION pos = GetFirstViewPosition();
while (pos != NULL)
{
CView* pView = GetNextView(pos);
pView->GetParentFrame()->GetWindowText(Title);
if(Title.Find("Search Spy") != -1)
((CViewSearchSpy *) pView)->AddSearchTerm( searchText );
}
}
/////////////////////////////////////////////////////////////////////////////
// CGnucleusDoc diagnostics
#ifdef _DEBUG
void CGnucleusDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CGnucleusDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CGnucleusDoc commands